import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
# Suppress only a specific future warning
warnings.filterwarnings("ignore", message=".*use_inf_as_na option is deprecated.*", category=FutureWarning)
warnings.filterwarnings("ignore", message=".*Pass `(name,)` instead of `name`.*", category=FutureWarning)
Extracted Datasets for GEE:
MOD13A1(Frequency: 15days)
ERA5_LAND(HOURLY)
CHIRPS (Weekly):
data_path = {
'sentinel': "/kaggle/input/climate-crop/Sentinel_2_NDVI_Timeseries.csv",
"MOD13A1": '/kaggle/input/climate-crop/NDVI_Timeseries_3km_MyRegion_26july(1).csv',
"MOD11A1" : '/kaggle/input/climate-crop/MODIS11A1_MyRegion_26july.csv',
"ERA5_LAND": '/kaggle/input/climate-crop/ERA5_land_3km_MyRegion_26july.csv',
"CHIRPS":'/kaggle/input/climate-crop/CHIRPS_3km_MyRegion_26july.csv'
}
data_description = {
"MOD13A1":[
{
"feature_name":"NDVI",
"unit":"",
"scale":0.0001,
"offset": 0,
"min":-2000,
"max": 10000,
"description" : "Normalized Difference Vegetation Index"
},
{
"feature_name":"EVI",
"unit":"",
"scale":0.0001,
"offset": 0,
"min":-2000,
"max": 10000,
"description":"Enhanced Vegetation Index"
},
{
"feature_name":"DetailedQA",
"unit": "",
"scale": 1,
"offset" : 0,
"description":"VI quality indicators"
},
{
"feature_name":"sur_refl_b01",
"unit": "",
"scale": 0.0001,
"offset" : 0,
"min":0,
"max": 10000,
"wavelength":"645mm",
"description":"Red surface reflectance"
},
{
"feature_name":"sur_refl_b02",
"unit": "",
"scale": 0.0001,
"offset" : 0,
"min":0,
"max": 10000,
"wavelength":"645mm",
"description": "NIR surface reflectance"
},
{
"feature_name":"sur_refl_b03",
"unit": "",
"scale": 0.0001,
"offset" : 0,
"min":0,
"max": 10000,
"wavelength":"645mm",
"description":"Blue surface reflectance"
},
{
"feature_name":"sur_refl_b07",
"unit": "",
"scale": 0.0001,
"offset" : 0,
"min":0,
"max": 10000,
"wavelength":"2130nm/2105 - 2155nm",
"description":"MIR surface reflectance"
},
{
"feature_name":"SummaryQA",
"unit": "",
"scale": 1,
"offset" : 0,
"description": "Quality reliability of VI pixel"
}
],
"MOD11A1":[
{
"feature_name":"LST_Day_1km",
"unit": "K",
"scale": 0.02,
"offset" : 0,
"min":7500,
"max": 65535,
"description": "Daytime Land Surface Temperature"
},
{
"feature_name":"QC_Day",
"unit": "",
"scale": 1,
"offset" : 0,
"description": "Daytime LST Quality Indicators"
},
{
"feature_name":"LST_Night_1km",
"unit": "K",
"scale": 0.02,
"offset" : 0,
"min":7500,
"max": 65535,
"description": "Nighttime Land Surface Temperature"
}
],
"ERA5_LAND":[
{
"feature_name":"temperature_2m",
"unit": "K",
"scale": 1,
"offset" : 0,
"description": "Temperature to which the air, at 2 meters above the surface of the Earth"
},
{
"feature_name":"dewpoint_temperature_2m",
"unit": "K",
"scale": 1,
"offset" : 0,
"description": "Temperature to which the air, at 2 meters above the surface of the Earth, would have to be cooled for saturation to occur. It is a measure of the humidity of the air."
},
{
"feature_name":"surface_pressure",
"unit": "Pa",
"scale": 1,
"offset" : 0,
"description": "Pressure (force per unit area) of the atmosphere on the surface of land, sea and in-land water."
},
{
"feature_name":"skin_temperature",
"unit": "K",
"scale": 1,
"offset" : 0,
"description": "Temperature of the surface of the Earth."
},
{
"feature_name":"soil_temperature_level_1",
"unit": "K",
"scale": 1,
"offset" : 0,
"description": "Temperature of the soil in layer 1 (0 - 7 cm)"
},
{
"feature_name":"soil_temperature_level_2",
"unit": "K",
"scale": 1,
"offset" : 0,
"description": "Temperature of the soil in layer 2 (7-28 cm)"
},
{
"feature_name":"soil_temperature_level_3",
"unit": "K",
"scale": 1,
"offset" : 0,
"description": "Temperature of the soil in layer 2 (28-100 cm)"
},
{
"feature_name":"soil_temperature_level_4",
"unit": "K",
"scale": 1,
"offset" : 0,
"description": "Temperature of the soil in layer 2 (100-289 cm)"
},
{
"feature_name":"volumetric_soil_water_layer_1",
"unit": "Volume fraction",
"scale": 1,
"offset" : 0,
"description": "Volume of water in soil layer 1 (0 - 7 cm)"
},
{
"feature_name":"volumetric_soil_water_layer_2",
"unit": "Volume fraction",
"scale": 1,
"offset" : 0,
"description": "Volume of water in soil layer 2 (7 - 28 cm)"
},
{
"feature_name":"volumetric_soil_water_layer_3",
"unit": "Volume fraction",
"scale": 1,
"offset" : 0,
"description": "Volume of water in soil layer 3 (28 - 100 cm)"
},
{
"feature_name":"volumetric_soil_water_layer_4",
"unit": "Volume fraction",
"scale": 1,
"offset" : 0,
"description": "Volume of water in soil layer 4 (100 - 289 cm)"
}
],
"sentinel": [
{'feature_name': 'QA20',
'unit': '',
'scale': 1,
'offset': 0,
'description': ''},
{'feature_name': 'B2',
'unit': '',
'scale': 0.0001,
'offset': 0,
'description': ''},
{'feature_name': 'B10',
'unit': '',
'scale': 0.0001,
'offset': 0,
'description': ''},
{'feature_name': 'B11',
'unit': '',
'scale': 0.0001,
'offset': 0,
'description': ''},
{'feature_name': 'B8',
'unit': '',
'scale': 0.0001,
'offset': 0,
'description': ''},
{'feature_name': 'B9',
'unit': '',
'scale': 0.0001,
'offset': 0,
'description': ''},
{'feature_name': 'B7',
'unit': '',
'scale': 0.0001,
'offset': 0,
'description': ''},
{'feature_name': 'NDVI',
'unit': '',
'scale': 1,
'offset': 0,
'description': ''},
{'feature_name': 'B3',
'unit': '',
'scale': 0.0001,
'offset': 0,
'description': ''},
{'feature_name': 'B5',
'unit': '',
'scale': 0.0001,
'offset': 0,
'description': ''},
{'feature_name': 'B12',
'unit': '',
'scale': 0.0001,
'offset': 0,
'description': ''},
{'feature_name': 'B4',
'unit': '',
'scale': 0.0001,
'offset': 0,
'description': ''},
{'feature_name': 'B8A',
'unit': '',
'scale': 0.0001,
'offset': 0,
'description': ''},
{'feature_name': 'B1',
'unit': '',
'scale': 0.0001,
'offset': 0,
'description': ''},
{'feature_name': 'B6',
'unit': '',
'scale': 0.0001,
'offset': 0,
'description': ''},
],
"CHIRPS":[
{
"feature_name":"precipitation",
"unit": "mm/pentad",
"scale": 1,
"offset" : 0,
"min": 0,
"max": 1072,
"description": "Precipitation"
}
]
}
data_collection = {}
for name,path in data_path.items():
df = pd.read_csv(path)
for feature_disc in data_description[name]:
feature_name = feature_disc['feature_name']
stats = ["_mean","_max","_min","_stdDev"]
feature_name_stat = [feature_name + s for s in stats ]
if('scale' in feature_disc):
scale = feature_disc['scale']
else:
scale = 1
if('offset' in feature_disc):
offset = feature_disc['offset']
else:
offset = 0
for fn in feature_name_stat:
df[fn] = df[fn]*scale + offset
if('.geo' in df.columns):
df.drop(columns = '.geo',inplace = True)
data_collection[name] = df.copy()
####
columns_modis_13A1 = ['date', 'region', 'state','buffer_km','DetailedQA_max', 'DetailedQA_mean', 'DetailedQA_min',
'DetailedQA_stdDev', 'EVI_max', 'EVI_mean', 'EVI_min', 'EVI_stdDev',
'NDVI_max', 'NDVI_mean', 'NDVI_min', 'NDVI_stdDev', 'SummaryQA_max',
'SummaryQA_mean', 'SummaryQA_min', 'SummaryQA_stdDev', 'sur_refl_b01_max', 'sur_refl_b01_mean',
'sur_refl_b01_min', 'sur_refl_b01_stdDev', 'sur_refl_b02_max',
'sur_refl_b02_mean', 'sur_refl_b02_min', 'sur_refl_b02_stdDev',
'sur_refl_b03_max', 'sur_refl_b03_mean', 'sur_refl_b03_min',
'sur_refl_b03_stdDev', 'sur_refl_b07_max', 'sur_refl_b07_mean',
'sur_refl_b07_min', 'sur_refl_b07_stdDev']
data_collection['MOD13A1'] = data_collection['MOD13A1'][columns_modis_13A1]
data_collection['MOD13A1']['date'] = pd.to_datetime(data_collection['MOD13A1']['date'])
data_collection['MOD13A1'] = data_collection['MOD13A1'].sort_values(['date','state','region']).reset_index(drop = True)
#####
columns_modis_11A1 = [ 'date', 'region', 'state' , 'buffer_km', 'LST_Day_1km_max', 'LST_Day_1km_mean',
'LST_Day_1km_min', 'LST_Day_1km_stdDev', 'LST_Night_1km_max',
'LST_Night_1km_mean', 'LST_Night_1km_min', 'LST_Night_1km_stdDev',
'QC_Day_max', 'QC_Day_mean', 'QC_Day_min', 'QC_Day_stdDev']
data_collection['MOD11A1'] = data_collection['MOD11A1'][columns_modis_11A1]
data_collection['MOD11A1']['date'] = pd.to_datetime(data_collection['MOD11A1']['date'])
data_collection['MOD11A1'] = data_collection['MOD11A1'].sort_values(['date','state','region']).reset_index(drop = True)
data_collection['CHIRPS'].columns
####
CHIRPS_columns =[ 'date','state','region','buffer_km', 'precipitation_max',
'precipitation_mean', 'precipitation_min', 'precipitation_stdDev']
data_collection['CHIRPS'] = data_collection['CHIRPS'][CHIRPS_columns]
data_collection['CHIRPS']['date'] = pd.to_datetime(data_collection['CHIRPS']['date'])
data_collection['CHIRPS'] = data_collection['CHIRPS'].sort_values(['date','state','region']).reset_index(drop = True)
####
ERA5_LAND_columns = ['date','state','buffer_km','region','dewpoint_temperature_2m_max',
'dewpoint_temperature_2m_mean', 'dewpoint_temperature_2m_min',
'dewpoint_temperature_2m_stdDev', 'skin_temperature_max',
'skin_temperature_mean', 'skin_temperature_min',
'skin_temperature_stdDev', 'soil_temperature_level_1_max',
'soil_temperature_level_1_mean', 'soil_temperature_level_1_min',
'soil_temperature_level_1_stdDev', 'soil_temperature_level_2_max',
'soil_temperature_level_2_mean', 'soil_temperature_level_2_min',
'soil_temperature_level_2_stdDev', 'soil_temperature_level_3_max',
'soil_temperature_level_3_mean', 'soil_temperature_level_3_min',
'soil_temperature_level_3_stdDev', 'soil_temperature_level_4_max',
'soil_temperature_level_4_mean', 'soil_temperature_level_4_min',
'soil_temperature_level_4_stdDev', 'surface_pressure_max',
'surface_pressure_mean', 'surface_pressure_min',
'surface_pressure_stdDev', 'temperature_2m_max', 'temperature_2m_mean',
'temperature_2m_min', 'temperature_2m_stdDev',
'volumetric_soil_water_layer_1_max',
'volumetric_soil_water_layer_1_mean',
'volumetric_soil_water_layer_1_min',
'volumetric_soil_water_layer_1_stdDev',
'volumetric_soil_water_layer_2_max',
'volumetric_soil_water_layer_2_mean',
'volumetric_soil_water_layer_2_min',
'volumetric_soil_water_layer_2_stdDev',
'volumetric_soil_water_layer_3_max',
'volumetric_soil_water_layer_3_mean',
'volumetric_soil_water_layer_3_min',
'volumetric_soil_water_layer_3_stdDev',
'volumetric_soil_water_layer_4_max',
'volumetric_soil_water_layer_4_mean',
'volumetric_soil_water_layer_4_min',
'volumetric_soil_water_layer_4_stdDev']
data_collection['ERA5_LAND'] = data_collection['ERA5_LAND'][ERA5_LAND_columns]
data_collection['ERA5_LAND']['date'] = pd.to_datetime(data_collection['ERA5_LAND']['date'])
data_collection['ERA5_LAND'] = data_collection['ERA5_LAND'].sort_values(['date','state','region']).reset_index(drop = True)
# data_collection['sentinel'].columns , ['NDVI_max', 'NDVI_mean', 'NDVI_min', 'NDVI_stdDev']
senitenl_columns =[ 'date','state','region','buffer_km'] + ['NDVI_max', 'NDVI_mean', 'NDVI_min', 'NDVI_stdDev']
data_collection['sentinel'] = data_collection['sentinel'][senitenl_columns]
data_collection['sentinel']['date'] = pd.to_datetime(data_collection['sentinel']['date'])
data_collection['sentinel'] = data_collection['sentinel'].sort_values(['date','state','region']).reset_index(drop = True)
# !pip install --upgrade seaborn -q
import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
df = data_collection['MOD13A1'].copy()
df['month'] = df['date'].map(lambda x: x.month)
df['year'] = df['date'].map(lambda x: x.year)
df = df.sort_values("date")
data_collection['MOD13A1'] = df
df = data_collection['sentinel'].copy()
df['month'] = df['date'].map(lambda x: x.month)
df['year'] = df['date'].map(lambda x: x.year)
df = df.sort_values("date")
data_collection['sentinel'] = df
data_collection['sentinel'] = data_collection['sentinel'].dropna(axis=0)
def ema(data, alpha):
ema_vals = [data[0]] # start with the first data point
for val in data[1:]:
ema_vals.append(alpha * val + (1 - alpha) * ema_vals[-1])
return ema_vals
# df_2 = df_1.groupby(['state','region','year','crop' ])[['NDVI_mean','NDVI_max']].max().reset_index()###peak nvdi
##classify crop based on the months
def func_crop_mp(x):
if(x>=7 and x<11):
return 'kharif'
elif(x>=11 or x<=4):
return 'rabi'
else:
return 'nocrop'
def func_crop_MH(x):
if(x>=6 and x<10):
return 'kharif'
elif(x>=10 or x<6):
return 'rabi'
else:
return 'nocrop'
def fun_mark_crop(data):
state = data.state.unique()
dfs = []
for s in state:
if(s =='MP'):
df = data[data.state == s].copy()
df['crop'] = df['month'].map(func_crop_mp)
dfs.append(df)
elif(s == 'MH'):
df = data[data.state == s].copy()
df['crop'] = df['month'].map(func_crop_MH)
dfs.append(df)
dfs = pd.concat(dfs,axis =0)
return dfs
data_collection['sentinel'] = fun_mark_crop(data_collection['sentinel'])
data_collection['MOD13A1'] = fun_mark_crop(data_collection['MOD13A1'])
df_1 = data_collection['sentinel'].copy()
df_2 = data_collection['MOD13A1'].groupby(['state','region','year','crop' ])[['NDVI_mean','NDVI_max']].max().reset_index()###peak nvdi
crops = ['kharif','rabi']
state = ['MH','MP']#,'MH']
# state = ['MP']#,'MH']
for s in state:
df_3 = df_1[(df_1.state == s) ].copy().iloc[:2000]
# NDVI_mean plot
for region in df_3.region.unique():
data = df_3[df_3.region == region]['NDVI_mean'].values
date = df_3[df_3.region == region]['date'].values
data = np.array(list(data))
if(s =='MH'):
alpha = 0.3
else:
alpha = 0.3
ema_vals = np.array(ema(data, alpha=alpha))
df_3_ = df_3[df_3.region == region]
df_3_ = df_3_.loc[df_3_[['month','year']].drop_duplicates(keep = 'first').index]
plt.figure(figsize = (30,5))
sns.lineplot(x =date , y = ema_vals,alpha=0.9,label = 'exponential_moving_average_NVDI')
sns.lineplot(x =date , y = data,alpha=0.1,label = 'NVDI')
def add_vertical_line(dates,color,label):
added_label = False
for d in dates:
if not added_label:
plt.axvline(x=d, color=color, linestyle='--', label=label)
added_label = True
else:
plt.axvline(x=d, color=color, linestyle='--')
if(s == 'MP'):
months = [7,11,4]
labels = ['July','November','April']
colors = ['black','red','blue']
else:
months = [6,11]
labels = ['June','November']
colors = ['black','red']
for m ,c ,l in zip(months,colors,labels):
date_vertical_line = df_3_[df_3_['month'] ==m]['date'].values
add_vertical_line(date_vertical_line,color = c ,label = l )
plt.legend()
plt.title(f"state:{s} region:{region} - Timeseries NVDI")
plt.show()
for crop in crops:
print(f"state:{s} crop:{crop}")
df_4 = df_2[(df_2.state == s) & (df_2.crop ==crop ) ].copy()
##peak NVDI year on year
plt.figure(figsize = (30,5))
ax = sns.lineplot(data=df_4, x='year', y='NDVI_mean',hue = 'region')
ax.set_title(f'state: {s} - peak NVDI for {crop}')
plt.show()
state:MH crop:kharif
state:MH crop:rabi
state:MP crop:kharif
state:MP crop:rabi
data_chirps = data_collection['CHIRPS'].copy()
data_chirps['month'] = data_chirps['date'].map(lambda x: x.month)
data_chirps['year'] = data_chirps['date'].map(lambda x: x.year)
# data_chirps['crop'] = data_chirps['month'].map(func_crop)
data_chirps = fun_mark_crop(data_chirps)
data_chirps = data_chirps.sort_values("date")
data_collection['CHIRPS'] = data_chirps
data_chirps_grp = data_chirps.groupby(['year','month','state','region','crop'])['precipitation_mean'].mean().reset_index().copy()
# data_chirps_grp['month_year']
data_chirps_grp['month-year'] = data_chirps_grp[['month','year']].apply(func = lambda x: str(x[0]) + "-" + str(x[1]) ,axis=1)
crops = ['kharif']
state = ['MP','MH']
for s in state:
for crop in crops:
print(f"state:{s} crop:{crop}")
df = data_chirps_grp.copy()
df = df[(df.state == s)].copy()
# df_1 = df[(df.crop ==region)].copy()
# NDVI_mean plot
plt.figure(figsize = (30,5))
ax = sns.lineplot(data = df, x='month-year', y='precipitation_mean', hue='region')
ax.set_title(f'state: {s} - NDVI_mean over time by crop')
xticks = df['month-year'].unique()[::5] # every 4th tick
ax.set_xticks([])
ax.set_xticks(xticks)
ax.tick_params(axis='x', rotation=45)
plt.show()
state:MP crop:kharif
state:MH crop:kharif
### Merge NDVI and precipitation data
def func(x,df_2):
offset = pd.DateOffset(months=0, days=15)
x1 = x.iloc[0]
x2 = x.iloc[1]
if(pd.isna(x1)):
return np.NaN
elif(pd.isna(x2)):
x2 = x1 - offset
else:
pass
df_2 = df_2[(df_2['date'] <=x1) & (df_2['date'] > x2) ]
mean_val = df_2[['precipitation_max','precipitation_mean', 'precipitation_min', 'precipitation_stdDev']].mean()
mean_val['date'] = x1
return mean_val
data_ndvi = data_collection['MOD13A1'].copy()
data_ndvi_pre = []
for (s,r),grp in data_ndvi.groupby(['state','region']):
grp['prev_date'] = grp['date'].shift(1)
df_2 = data_chirps[(data_chirps['state'] == s) & (data_chirps['region'] == r)].copy()
mean_val = grp[['date','prev_date','state','region']].apply(lambda x: func(x,df_2) ,axis=1)
mean_val['state'] = s
mean_val['region'] = r
data_ndvi_pre.append(mean_val)
data_ndvi_pre = pd.concat(data_ndvi_pre,axis = 0)
data_ndvi_precipitation = data_ndvi.merge(data_ndvi_pre , on =['date','region','state'])
### year on year
columns_to_corr = [ 'NDVI_max', 'NDVI_mean','NDVI_min', 'precipitation_max', 'precipitation_mean','precipitation_min']
data_ndvi_year_crop = data_ndvi_precipitation.groupby(['state','region','year','crop',])[[ 'NDVI_max', 'NDVI_mean','NDVI_min', 'precipitation_max', 'precipitation_mean','precipitation_min']].agg(
NDVI_peak =pd.NamedAgg(column="NDVI_mean", aggfunc="max"),
precipitation_mean =pd.NamedAgg(column="precipitation_mean", aggfunc="mean"),
precipitation_max =pd.NamedAgg(column="precipitation_mean", aggfunc="max"),
precipitation_std =pd.NamedAgg(column="precipitation_mean", aggfunc="std") )
data_ndvi_year_crop = data_ndvi_year_crop.reset_index()
data_ndvi_year_crop[data_ndvi_year_crop.crop == 'kharif'].groupby('state')[['NDVI_peak','precipitation_mean','precipitation_max','precipitation_std']].corr(method = 'pearson')
| NDVI_peak | precipitation_mean | precipitation_max | precipitation_std | ||
|---|---|---|---|---|---|
| state | |||||
| MH | NDVI_peak | 1.000000 | 0.861122 | 0.739630 | 0.655773 |
| precipitation_mean | 0.861122 | 1.000000 | 0.853197 | 0.790803 | |
| precipitation_max | 0.739630 | 0.853197 | 1.000000 | 0.957131 | |
| precipitation_std | 0.655773 | 0.790803 | 0.957131 | 1.000000 | |
| MP | NDVI_peak | 1.000000 | 0.391582 | 0.385511 | 0.357111 |
| precipitation_mean | 0.391582 | 1.000000 | 0.864270 | 0.814800 | |
| precipitation_max | 0.385511 | 0.864270 | 1.000000 | 0.973891 | |
| precipitation_std | 0.357111 | 0.814800 | 0.973891 | 1.000000 |
sns.scatterplot(x = 'NDVI_peak',y = 'precipitation_mean',data = data_ndvi_year_crop[data_ndvi_year_crop.crop == 'kharif'] )
plt.title(f"NVDI_peak ")
plt.show()
#'EVI_max','EVI_mean', 'EVI_min', 'EVI_stdDev',
columns_to_corr = [ 'NVDI_peak', 'precipitation_mean', 'precipitation_std']
# regions = data_nvdi_precipitation[data_nvdi_precipitation.state == 'MP'].region.unique()
for state in data_nvdi_year_crop.state.unique():
df = data_nvdi_year_crop[data_nvdi_year_crop.state == state ].copy()
sns.scatterplot(x = 'NVDI_peak',y = 'precipitation_mean',data = df[ (df.crop == 'kharif')])
plt.title(f"state:{state} precipitation vs NVDI peak")
plt.show()
# fig,axis = plt.subplots(nrows = 1,ncols = 3,figsize = (30,5))
for i,region in enumerate(df.region.unique()):
print(f"region:{region}")
grp = df[ (df.crop == 'kharif') &
( df.region == region ) ]
corr = grp[columns_to_corr].corr()
print(f"",corr['NVDI_peak'].to_dict())
# sns.scatterplot(x = 'NVDI_peak',y = 'precipitation_mean',data = grp,ax = axis[i])
# plt.title(f'state:{s} region:{region}- plot ')
# plt.show()
region:jethabhawda
{'NVDI_peak': 1.0, 'precipitation_mean': -0.03296094341898041, 'precipitation_std': -0.10295944202284003}
region:mundhewadi
{'NVDI_peak': 1.0, 'precipitation_mean': 0.6093342342239988, 'precipitation_std': 0.2895558937319416}
region:tadklas
{'NVDI_peak': 1.0, 'precipitation_mean': 0.25343896516580444, 'precipitation_std': 0.3025331967625471}
region:ankia
{'NVDI_peak': 1.0, 'precipitation_mean': 0.6333165313716916, 'precipitation_std': 0.7003937873767907}
region:chholya
{'NVDI_peak': 1.0, 'precipitation_mean': 0.39135190160073674, 'precipitation_std': 0.2578683551461847}
region:kalyanpur
{'NVDI_peak': 1.0, 'precipitation_mean': 0.16938443195431488, 'precipitation_std': 0.14056152811403586}
data_era = data_collection['ERA5_LAND'].copy()
data_era['month'] = data_era['date'].map(lambda x:x.month)
data_era['year'] = data_era['date'].map(lambda x:x.year)
data_era["dewpoint_depression"] = data_era["temperature_2m_mean"] - data_era["dewpoint_temperature_2m_mean"]
data_era["surface_air_Temp_Diff"] = data_era["skin_temperature_mean"] - data_era["temperature_2m_mean"]
data_era["ratio_surface_air_temp"] = (data_era["temperature_2m_mean"] - data_era["dewpoint_temperature_2m_mean"]) / (data_era["skin_temperature_mean"] - data_era["dewpoint_temperature_2m_mean"])
columns_plot = ['temperature_2m_mean','dewpoint_temperature_2m_mean','skin_temperature_mean','soil_temperature_level_1_mean','volumetric_soil_water_layer_1_mean',
'dewpoint_depression','surface_air_Temp_Diff','ratio_surface_air_temp'
]
data_era_month = data_era.groupby(['region','month','year','state'])[columns_plot].mean()
data_era_month = data_era_month.reset_index().sort_values(['region','month','year','state'])
data_era_month['year_month'] = data_era_month[ ['year','month']].apply(lambda x: str(x[0]) + ' / ' +str(x[1]) ,axis = 1)
data_era_month = data_era_month.sort_values('year_month')
# data_era_month['diff_temp2m_surface'] = (-data_era_month['temperature_2m_mean'] + data_era_month['skin_temperature_mean'])
# data_era_month
crops = ['kharif','rabi']
state = ['MP','MH']
for s in state:
# for crop in crops:
# print(f"state:{s} crop:{crop}")
# tempreture plot
plt.figure(figsize = (30,5))
ax = sns.lineplot(data=data_era_month[data_era_month.state == s], x='year_month', y='temperature_2m_mean', hue='region')
ax.set_title(f'state: {s} - temperature_plot')
xticks = list(data_era_month[data_era_month.state == s]['year_month'].unique()[::5])
plt.xticks(xticks,rotation=45)
plt.title('temperature_2m_mean')
plt.show()
# tempreture plot
plt.figure(figsize = (30,5))
ax = sns.lineplot(data=data_era_month[data_era_month.state == s], x='year_month', y='diff_temp2m_surface', hue='region')
ax.set_title(f'state: {s} - temperature_plot')
xticks = list(data_era_month[data_era_month.state == s]['year_month'].unique()[::5])
plt.xticks(xticks,rotation=45)
plt.title('skin_temperature_mean')
plt.show()
### merge all data sets
def func(x,df_2):
offset = pd.DateOffset(months=0, days=15)
x1 = x.iloc[0]
x2 = x.iloc[1]
if(pd.isna(x1)):
return np.NaN
elif(pd.isna(x2)):
x2 = x1 - offset
else:
pass
df_2 = df_2[(df_2['date'] <=x1) & (df_2['date'] > x2) ]
columns = ['temperature_2m_mean','dewpoint_temperature_2m_mean','skin_temperature_mean', 'soil_temperature_level_1_mean', 'soil_temperature_level_2_mean','soil_temperature_level_3_mean',
'soil_temperature_level_4_mean', 'surface_pressure_mean','volumetric_soil_water_layer_1_mean','volumetric_soil_water_layer_2_mean','volumetric_soil_water_layer_3_mean','volumetric_soil_water_layer_4_mean',
'dewpoint_depression','surface_air_Temp_Diff','ratio_surface_air_temp']
mean_val = df_2[columns].mean()
mean_val['date'] = x1
return mean_val
data_merged = []
for (s,r),grp in data_ndvi_precipitation.groupby(['state','region']):
grp['prev_date'] = grp['date'].shift(1)
df_2 = data_era[(data_era['state'] == s) & (data_era['region'] == r)].copy()
mean_val = grp[['date','prev_date','state','region']].apply(lambda x: func(x,df_2) ,axis=1)
mean_val['state'] = s
mean_val['region'] = r
data_merged.append(mean_val)
data_merged = pd.concat(data_merged,axis = 0)
# data_nvdi_precipitation = data_nvdi.merge(data_ndvi_pre , on =['date','region','state'])
data_merged = data_ndvi_precipitation.merge(data_merged , on =['date','region','state'])
columns_to_corr = [ 'NDVI_max', 'NDVI_mean','NDVI_min'] + ['temperature_2m_mean','dewpoint_temperature_2m_mean','skin_temperature_mean', 'soil_temperature_level_1_mean', 'soil_temperature_level_2_mean','soil_temperature_level_3_mean',
'soil_temperature_level_4_mean', 'surface_pressure_mean','volumetric_soil_water_layer_1_mean','volumetric_soil_water_layer_2_mean','volumetric_soil_water_layer_3_mean','volumetric_soil_water_layer_4_mean']
columns_plot = ['skin_temperature_mean','soil_temperature_level_3_mean','volumetric_soil_water_layer_3_mean',]
for state in data_merged.state.unique():
grp = data_merged[(data_merged.state == state ) ]
# corr = grp[columns_to_corr].corr()
# print(corr['NDVI_mean'].to_dict())
for col in columns_plot:
fig,axes = plt.subplots(nrows = 1,ncols = 2,figsize = (20,5))
sns.scatterplot(data = grp[ (grp.crop == 'kharif')], x = col ,y = 'NDVI_mean',ax = axes[0],hue='region')
sns.scatterplot(data = grp[ (grp.crop == 'rabi')], x = col ,y = 'NDVI_mean',ax = axes[1],hue='region')
axes[0].set_title(f'state:{state} Kharif: {col} vs NDVI')
axes[1].set_title(f'state:{state} Rabi: {col} vs NDVI')
plt.show()
print('\n\n\n')
columns = ['NDVI_mean','EVI_mean'] + ['precipitation_mean','temperature_2m_mean','dewpoint_temperature_2m_mean','skin_temperature_mean', 'soil_temperature_level_1_mean', 'soil_temperature_level_2_mean','soil_temperature_level_3_mean',
'soil_temperature_level_4_mean', 'surface_pressure_mean','volumetric_soil_water_layer_1_mean','volumetric_soil_water_layer_2_mean','volumetric_soil_water_layer_3_mean','volumetric_soil_water_layer_4_mean',
'dewpoint_depression','surface_air_Temp_Diff','ratio_surface_air_temp']
corr = data_merged[data_merged.crop !="nocrop"].groupby(['state','region','crop'])[columns].corr(method = 'spearman')[["EVI_mean","NDVI_mean"]]
corr = corr.loc[[i for i in corr.index if (i[-1] not in ['EVI_mean','NDVI_mean'] ) ]]
pd.set_option("display.max_rows",100)
corr = corr[(np.abs(corr['NDVI_mean'])>0.6) | (np.abs(corr['EVI_mean'])>0.6)]
corr
| EVI_mean | NDVI_mean | ||||
|---|---|---|---|---|---|
| state | region | crop | |||
| MH | jethabhawda | kharif | soil_temperature_level_4_mean | -0.611169 | -0.656061 |
| volumetric_soil_water_layer_4_mean | 0.627993 | 0.613521 | |||
| rabi | volumetric_soil_water_layer_1_mean | 0.737807 | 0.777476 | ||
| volumetric_soil_water_layer_2_mean | 0.835457 | 0.879255 | |||
| volumetric_soil_water_layer_3_mean | 0.877224 | 0.924978 | |||
| volumetric_soil_water_layer_4_mean | 0.873363 | 0.920780 | |||
| dewpoint_depression | -0.858495 | -0.905209 | |||
| surface_air_Temp_Diff | -0.718841 | -0.763784 | |||
| mundhewadi | kharif | soil_temperature_level_4_mean | -0.666648 | -0.692576 | |
| volumetric_soil_water_layer_3_mean | 0.625681 | 0.568772 | |||
| volumetric_soil_water_layer_4_mean | 0.616920 | 0.532675 | |||
| rabi | temperature_2m_mean | -0.782975 | -0.756373 | ||
| skin_temperature_mean | -0.825953 | -0.814764 | |||
| soil_temperature_level_1_mean | -0.828818 | -0.815588 | |||
| soil_temperature_level_2_mean | -0.826330 | -0.809697 | |||
| soil_temperature_level_3_mean | -0.800639 | -0.774155 | |||
| volumetric_soil_water_layer_2_mean | 0.810662 | 0.826061 | |||
| volumetric_soil_water_layer_3_mean | 0.842076 | 0.852765 | |||
| dewpoint_depression | -0.773677 | -0.808108 | |||
| surface_air_Temp_Diff | -0.831518 | -0.841218 | |||
| ratio_surface_air_temp | 0.724422 | 0.726318 | |||
| tadklas | kharif | temperature_2m_mean | -0.633732 | -0.597927 | |
| skin_temperature_mean | -0.635747 | -0.586711 | |||
| soil_temperature_level_1_mean | -0.678819 | -0.633784 | |||
| soil_temperature_level_2_mean | -0.718544 | -0.678716 | |||
| soil_temperature_level_3_mean | -0.729211 | -0.703128 | |||
| soil_temperature_level_4_mean | -0.560743 | -0.600949 | |||
| volumetric_soil_water_layer_3_mean | 0.679666 | 0.634551 | |||
| dewpoint_depression | -0.621069 | -0.590191 | |||
| surface_air_Temp_Diff | -0.617921 | -0.539198 | |||
| rabi | temperature_2m_mean | -0.611591 | -0.649650 | ||
| skin_temperature_mean | -0.691745 | -0.734500 | |||
| soil_temperature_level_1_mean | -0.691253 | -0.735641 | |||
| soil_temperature_level_2_mean | -0.685620 | -0.730105 | |||
| soil_temperature_level_3_mean | -0.645672 | -0.681623 | |||
| volumetric_soil_water_layer_2_mean | 0.714079 | 0.768112 | |||
| volumetric_soil_water_layer_3_mean | 0.814815 | 0.848517 | |||
| volumetric_soil_water_layer_4_mean | 0.689735 | 0.713446 | |||
| dewpoint_depression | -0.786956 | -0.832554 | |||
| surface_air_Temp_Diff | -0.764836 | -0.803318 | |||
| MP | ankia | rabi | temperature_2m_mean | -0.737209 | -0.830130 |
| skin_temperature_mean | -0.699115 | -0.796956 | |||
| soil_temperature_level_1_mean | -0.726158 | -0.819518 | |||
| soil_temperature_level_2_mean | -0.758524 | -0.843822 | |||
| soil_temperature_level_3_mean | -0.829401 | -0.871911 | |||
| surface_pressure_mean | 0.573292 | 0.678332 | |||
| chholya | rabi | temperature_2m_mean | -0.899947 | -0.903519 | |
| skin_temperature_mean | -0.891641 | -0.905717 | |||
| soil_temperature_level_1_mean | -0.897818 | -0.908432 | |||
| soil_temperature_level_2_mean | -0.900256 | -0.900449 | |||
| soil_temperature_level_3_mean | -0.815868 | -0.782452 | |||
| surface_pressure_mean | 0.800828 | 0.814225 | |||
| dewpoint_depression | -0.736079 | -0.794171 | |||
| kalyanpur | rabi | temperature_2m_mean | -0.892532 | -0.885147 | |
| skin_temperature_mean | -0.888958 | -0.889377 | |||
| soil_temperature_level_1_mean | -0.885239 | -0.882922 | |||
| soil_temperature_level_2_mean | -0.872958 | -0.865073 | |||
| soil_temperature_level_3_mean | -0.747742 | -0.716336 | |||
| surface_pressure_mean | 0.763122 | 0.774025 | |||
| dewpoint_depression | -0.696972 | -0.745905 | |||
| surface_air_Temp_Diff | -0.553081 | -0.609246 |
Kharif Season Observations:
Surface-Air Temperature Difference and Soil Temperature at Level 4 (mean) are negatively correlated with NDVI.
Soil moisture volume is positively correlated with NDVI.
This is expected — higher surface-air temperature differences indicate more heat stress on crops.
Rabi Season Observations:
Surface-Air Temperature Difference and Soil Temperature at Level 4 (mean) are negatively correlated with NDVI.
The Surface-Air Temperature Ratio is positively correlated, which suggests that when the surface temperature is closer to the dew point, vapor near the surface condenses, increasing moisture availability.
Similarly, soil moisture volume shows a positive correlation with NDVI, indicating that higher moisture supports healthier crop growth.
selected_feature = corr.reset_index()['level_3'].unique()
selected_feature_str = '\n'.join(selected_feature)
print(f"selected_feature\n{selected_feature_str}")
selected_feature soil_temperature_level_4_mean volumetric_soil_water_layer_4_mean volumetric_soil_water_layer_1_mean volumetric_soil_water_layer_2_mean volumetric_soil_water_layer_3_mean dewpoint_depression surface_air_Temp_Diff temperature_2m_mean skin_temperature_mean soil_temperature_level_1_mean soil_temperature_level_2_mean soil_temperature_level_3_mean ratio_surface_air_temp surface_pressure_mean
Compare low NDVI with high NDVI periods to analyze how climatic factors or changes contribute to a decrease in NDVI.
columns = ['NDVI_mean','EVI_mean'] + ['precipitation_mean','temperature_2m_mean','dewpoint_temperature_2m_mean','skin_temperature_mean', 'soil_temperature_level_1_mean', 'soil_temperature_level_2_mean','soil_temperature_level_3_mean',
'soil_temperature_level_4_mean', 'surface_pressure_mean','volumetric_soil_water_layer_1_mean','volumetric_soil_water_layer_2_mean','volumetric_soil_water_layer_3_mean','volumetric_soil_water_layer_4_mean']
columns = ['NDVI_mean','EVI_mean'] + list(selected_feature)
data_merged_ndvi_peak = data_merged.groupby(['region','state','year','crop']).agg(
NDVI_peak = pd.NamedAgg(column = 'NDVI_mean',aggfunc = 'max') ,
precipitation_mean = pd.NamedAgg(column = 'precipitation_mean',aggfunc = 'mean'),
**{col:pd.NamedAgg(column = col,aggfunc = 'mean') for col in selected_feature}
)
data_merged_ndvi_peak = data_merged_ndvi_peak.reset_index()
# data_merged_ndvi_peak[(data_merged_ndvi_peak['year'] < 2024) &
# (data_merged_ndvi_peak.state == 'MH') &
# (data_merged_ndvi_peak.region == 'tadklas')&
# (data_merged_ndvi_peak.NDVI_peak > 0.6)].copy()
columns = ['NDVI_peak', 'precipitation_mean'] + list(selected_feature)
columns_best = [col + '_best' for col in columns]
columns_diff = [col + '_diff' for col in columns]
##cross join
data_merged_ndvi_peak_compare = data_merged_ndvi_peak.merge(data_merged_ndvi_peak,on = ['region','state','crop',],suffixes = ("","_best"),how = 'inner',)
# data_merged_nvdi_peak_compare = data_merged_nvdi_peak_compare[data_merged_nvdi_peak_compare['NDVI_peak'] < data_merged_nvdi_peak_compare['NDVI_peak_best']]
data_merged_ndvi_peak_compare = data_merged_ndvi_peak_compare.reset_index(drop = True)
data_diff = -data_merged_ndvi_peak_compare[columns_best].values + data_merged_ndvi_peak_compare[columns].values
df_diff = pd.DataFrame(data_diff,columns = columns_diff )
data_merged_ndvi_peak_compare = pd.concat([data_merged_ndvi_peak_compare , df_diff] ,axis=1 , ignore_index = False )
###filter out
columns_location = ['region', 'state', 'year', 'crop']
data_merged_ndvi_peak_compare = data_merged_ndvi_peak_compare[(data_merged_ndvi_peak_compare['NDVI_peak_diff'] < -0.1) &
(data_merged_ndvi_peak_compare['crop'] !='nocrop')][columns_location + ['NDVI_peak','NDVI_peak_best','year_best'] + columns_diff ]
# data_merged_ndvi_peak_compare
# df.groupby( ['region', 'state', 'year', 'crop'])
data_merged_compare = []
data_merged_ndvi_peak_compare = data_merged_ndvi_peak_compare[data_merged_ndvi_peak_compare['NDVI_peak_diff'] <-0.2]
for _,grp in data_merged_ndvi_peak_compare.groupby(['region', 'state', 'year', 'crop']):
grp = grp.sort_values('NDVI_peak_diff',ascending = True)[columns_location + ['NDVI_peak'] + ['year_best','NDVI_peak_best'] + columns_diff ]
grp = grp.iloc[:3] # select top 3 most difference point
if(grp.shape[0]==0):
continue
grp = grp.groupby(columns_location + ['NDVI_peak']).agg(
year_comparision = pd.NamedAgg(column = "year_best", aggfunc = lambda x: list(x)),
NDVI_peak_compare_mean = pd.NamedAgg(column = "NDVI_peak_best", aggfunc = 'mean' ),
**{col : pd.NamedAgg(column = col, aggfunc = 'mean' ) for col in columns_diff }
)
data_merged_compare.append(grp)
data_merged_compare = pd.concat(data_merged_compare,axis=0).reset_index()
pd.set_option("display.max_rows",100)
pd.set_option("display.max_columns",100)
data_merged_compare
| region | state | year | crop | NDVI_peak | year_comparision | NDVI_peak_compare_mean | NDVI_peak_diff | precipitation_mean_diff | soil_temperature_level_4_mean_diff | volumetric_soil_water_layer_4_mean_diff | volumetric_soil_water_layer_1_mean_diff | volumetric_soil_water_layer_2_mean_diff | volumetric_soil_water_layer_3_mean_diff | dewpoint_depression_diff | surface_air_Temp_Diff_diff | temperature_2m_mean_diff | skin_temperature_mean_diff | soil_temperature_level_1_mean_diff | soil_temperature_level_2_mean_diff | soil_temperature_level_3_mean_diff | ratio_surface_air_temp_diff | surface_pressure_mean_diff | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | ankia | MP | 2008 | kharif | 0.413144 | [2024, 2020, 2023] | 0.798610 | -0.385467 | -49.771530 | -1.064967 | -0.032901 | -0.143674 | -0.111088 | -0.037961 | 6.536435 | -0.344949 | 0.236451 | -0.108498 | 0.048834 | -0.084026 | -0.548897 | -5.209105 | 501.240483 |
| 1 | chholya | MP | 2008 | kharif | 0.362551 | [2009, 2022, 2012] | 0.774188 | -0.411637 | -39.664792 | -1.730536 | 0.027145 | -0.138592 | -0.092135 | -0.023104 | 6.392104 | -0.151916 | -0.246453 | -0.398369 | -0.424047 | -0.626511 | -1.243786 | 8.266652 | 678.886749 |
| 2 | chholya | MP | 2008 | rabi | 0.403128 | [2020, 2022, 2021] | 0.684985 | -0.281857 | -0.109536 | 2.311794 | 0.012388 | -0.020288 | -0.013754 | 0.012977 | -0.927134 | -0.370082 | 0.495657 | 0.125575 | 0.320195 | 0.718851 | 1.675075 | 0.724567 | 73.720189 |
| 3 | chholya | MP | 2009 | rabi | 0.468439 | [2020, 2022] | 0.706330 | -0.237891 | 0.147807 | 1.327762 | -0.022056 | 0.005077 | 0.008653 | -0.000027 | 1.193365 | -0.176464 | 1.520571 | 1.344107 | 1.371152 | 1.401002 | 1.410157 | 1.837445 | -75.212005 |
| 4 | chholya | MP | 2010 | rabi | 0.496936 | [2020] | 0.725693 | -0.228757 | 0.892684 | 0.710861 | -0.031640 | 0.017307 | 0.013547 | 0.011205 | 1.629150 | -0.306452 | 2.109842 | 1.803390 | 1.745053 | 1.636700 | 1.310301 | 1.830405 | -181.723212 |
| 5 | chholya | MP | 2011 | rabi | 0.477868 | [2020, 2022] | 0.706330 | -0.228462 | -0.511909 | 1.008105 | -0.022962 | -0.028820 | -0.016229 | -0.017176 | 3.089127 | 0.368321 | 1.503882 | 1.872203 | 1.862555 | 1.797059 | 1.524258 | 0.769925 | -128.306961 |
| 6 | chholya | MP | 2012 | rabi | 0.439636 | [2020, 2022, 2021] | 0.684985 | -0.245349 | -0.247348 | 0.578237 | -0.002565 | -0.021378 | -0.019367 | -0.022515 | 2.739291 | 0.362947 | 0.318097 | 0.681044 | 0.705155 | 0.698321 | 0.660792 | 0.813521 | -87.927388 |
| 7 | chholya | MP | 2013 | rabi | 0.483926 | [2020, 2022] | 0.706330 | -0.222404 | 0.093640 | 0.727959 | -0.006117 | -0.005448 | -0.003995 | -0.021077 | 1.163234 | 0.063705 | 0.374749 | 0.438454 | 0.484331 | 0.568787 | 0.726177 | 0.837819 | -41.001455 |
| 8 | kalyanpur | MP | 2008 | kharif | 0.365796 | [2023, 2009, 2010] | 0.834287 | -0.468491 | -39.201574 | -1.872820 | 0.009793 | -0.139234 | -0.098407 | -0.028934 | 6.911499 | 0.029671 | 0.065361 | 0.095032 | 0.065963 | -0.192362 | -0.990226 | -0.262253 | 646.642460 |
| 9 | kalyanpur | MP | 2013 | kharif | 0.518719 | [2023, 2009, 2010] | 0.834287 | -0.315567 | 18.221420 | -1.626116 | 0.029808 | 0.009610 | 0.002496 | -0.001927 | -1.154931 | -0.026266 | -1.053033 | -1.079300 | -1.269393 | -1.376085 | -1.644444 | 0.259921 | -69.993772 |
| 10 | kalyanpur | MP | 2016 | kharif | 0.625774 | [2023, 2009, 2010] | 0.834287 | -0.208513 | 14.838393 | -0.175658 | 0.015311 | 0.009108 | 0.010238 | -0.003733 | -0.176229 | -0.088328 | -0.826217 | -0.914545 | -0.911119 | -0.847006 | -0.670660 | -83.540841 | 70.963590 |
| 11 | kalyanpur | MP | 2018 | kharif | 0.513593 | [2023, 2009, 2010] | 0.834287 | -0.320693 | -1.382934 | -0.231078 | 0.003622 | 0.004959 | 0.006835 | 0.008800 | -0.031610 | -0.233182 | -0.819082 | -1.052264 | -1.111045 | -1.074520 | -0.894330 | 0.741106 | 30.687946 |
| 12 | kalyanpur | MP | 2019 | kharif | 0.577027 | [2023, 2009, 2010] | 0.834287 | -0.257259 | 43.604312 | 0.014243 | 0.013224 | 0.028618 | 0.018045 | 0.023445 | -1.462648 | 0.025843 | -0.690813 | -0.664970 | -0.686655 | -0.594527 | -0.358931 | 0.032606 | 8.225154 |
| 13 | mundhewadi | MH | 2009 | kharif | 0.371694 | [2024] | 0.589234 | -0.217540 | -6.409343 | 0.567265 | -0.098639 | -0.103800 | -0.063753 | -0.071001 | 1.943632 | 0.919856 | 0.770227 | 1.690083 | 1.637233 | 1.488569 | 1.150513 | -0.213790 | -13.055316 |
| 14 | mundhewadi | MH | 2011 | kharif | 0.383520 | [2024] | 0.589234 | -0.205714 | -8.408157 | -0.800455 | -0.068657 | -0.062373 | -0.039740 | -0.056462 | 0.883455 | 0.267527 | -0.117499 | 0.150028 | 0.084421 | -0.006763 | -0.244147 | -0.155525 | -76.422178 |
| 15 | mundhewadi | MH | 2012 | kharif | 0.352186 | [2024] | 0.589234 | -0.237048 | -10.624862 | 0.677730 | -0.085438 | -0.173429 | -0.115963 | -0.126016 | 3.217276 | 1.134354 | 1.106298 | 2.240653 | 2.133013 | 1.991827 | 1.593676 | -0.328333 | -56.316473 |
| 16 | tadklas | MH | 2015 | kharif | 0.577370 | [2024, 2022, 2023] | 0.834395 | -0.257025 | -13.379422 | 0.492744 | -0.066782 | -0.048630 | -0.043916 | -0.064285 | 2.063330 | 0.065937 | 1.063738 | 1.129675 | 1.117046 | 1.068273 | 0.917320 | 0.061601 | 36.166049 |
The above table presents a comparison across different years to identify which climatic variables may be contributing to a decline in NDVI.
| Year | State | Region | What Happened(referred from above table) | Source to Verify | |
|---|---|---|---|---|---|
| 2013 | MP | Kalyanpur | Excessive Rainfall during Kharif season | In 2013, Madhya Pradesh did experience excessive rainfall during the monsoon season, which led to crop damage in some areas | |
| 2016 | MP | Kalyanpur | Excessive Rainfall during Kharif season | https://reliefweb.int/report/india/casa-report-floods-situation-madhya-pradesh) | |
| 2008 | MP | chholya | Excessive Heat During Rabi (+2 deg) | https://imdpune.gov.in/library/public/Disastrous%20Weather%20Events%202008.pdf |
# corr[corr.level_3 == 'precipitation_mean']